from __future__ import print_function

from kivy.core.window import Window
from kivy.clock import mainthread
from kivy.metrics import sp
from kivy.properties import BooleanProperty, NumericProperty,\
    ObjectProperty
from extensions.garden.recycleview import RecycleView


class GoblinRecycleView(RecycleView):

    feed_service = ObjectProperty()

    refreshing_feed = BooleanProperty(False)
    updating_feed = BooleanProperty(False)
    animation_delegate = ObjectProperty()
    old_height = NumericProperty(0)
    container_height = NumericProperty()

    def __init__(self, **kwargs):
        super(GoblinRecycleView, self).__init__(**kwargs)
        self._container.bind(height=self.update_container_height)
        self.data.append(dict([
            ('viewclass', 'Label')]))

    def update_feed_data(self, updated_data):
        self.updating_feed = True
        self.disabled = True
        self.scroll_y = 1
        self.refresh_feed_with_new_data(updated_data)
        self.disabled = False
        self.updating_feed = False

    def update_container_height(self, instance, height):
        self.container_height = height

    def on_container_height(self, instance, height):
        if height > 0:
            self.scroll_y = 1 - self.old_height / height
        else:
            self.scroll_y = 1
        # for debugging
        # print ('updated scroll_y: {0}'.format(self.scroll_y))
        # print ('height before and after: {0}, {1}'.format(
        #     self.old_height,
        #     height * (1 - self.scroll_y)))

    @mainthread
    def request_feed_refresh(self):
        app_will_refresh = self.feed_service.start_refresh(
            self.refresh_feed_with_new_data)
        if app_will_refresh:
            self.refreshing_feed = True

    def on_scroll_y(self, instance, pos):
        if self._container.height > 0:
            self.old_height = (1 - self.scroll_y) * self._container.height
        if len(self.data) != 0:
            if pos < 1/(float((len(self.data)) ** (1.0/3))):
                self.feed_service.start_prefetch(self.append_prefetched_data)

    def on_refreshing_feed(self, instance, refreshing):
        if refreshing:
            self.disabled = True
        else:
            self.disabled = False

    def refresh_feed_with_new_data(self, data_list):
        if data_list is None:
            print ('data_list is None!')
            self.animation_delegate.on_no_service()
        elif len(data_list) > 0:
            self.refresh_feed(data_list)
            self.animation_delegate.on_feed_refreshed()
        else:
            print ('data_list is zero')
            self.animation_delegate.on_feed_refreshed()
        self.refreshing_feed = False

    def refresh_feed(self, data_list, *args):
        while len(self.data) > 0:
            self.data.pop()
        for data_item in data_list:
            self.data.append(data_item)

    def determine_container_height(self):
        height_diff = self._container.height - Window.height
        if height_diff <= 0:
            self.data.append(dict([
                ('viewclass', 'Label'),
                ('height', -1*height_diff + sp(20))]))

    def append_prefetched_data(self, data_list):
        if data_list is None:
            self.animation_delegate.on_no_service()
        else:
            self.data.extend(data_list)

    # NOTE: we only want to disable the rv, not its children
    def on_disabled(self, instance, value):
        pass
